package io.github.fb513.api.config;

import com.auth0.jwt.exceptions.TokenExpiredException;
import io.github.fb513.api.enums.RespMetaEnum;
import io.github.fb513.api.exception.WebBaseException;
import io.github.fb513.common.util.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import java.util.Map;

@Slf4j
@Component
public class LoginResolver implements HandlerMethodArgumentResolver {

    @Value("${spring.profiles.active}")
    private String profiles;

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.getParameterType().isAssignableFrom(Long.class) && parameter.hasParameterAnnotation(Login.class);
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer container,
                                  NativeWebRequest request, WebDataBinderFactory factory) {
        String token = request.getHeader(HttpHeaders.AUTHORIZATION);
        if (!StringUtils.hasLength(token)) {
            throw new WebBaseException(RespMetaEnum.NOT_LOGIN);
        }
        token = token.trim();

        Long userId = null;
        try {
            Map<String, Object> tokenParams = JwtUtils.verifyToken(token);
            Object userIdObj = tokenParams.get("userId");
            if (userIdObj != null) {
                userId = Long.valueOf(userIdObj.toString());
            }
        } catch (TokenExpiredException e) {
            log.info("Token过期", e);
        } catch (NumberFormatException e) {
            log.error("解析用户ID错误", e);
        } catch (Exception e) {
            log.error("解析Token错误", e);
        }
        if (userId == null) {
            throw new WebBaseException(RespMetaEnum.NOT_LOGIN);
        }
        return userId;
    }

}
